package city.spring.modules.material.controller;

import city.spring.modules.material.entity.*;
import city.spring.modules.material.repository.MaterialdeliveryMaterialExtRepository;
import city.spring.modules.material.repository.MaterialreceiptMaterialExtRepository;
import city.spring.modules.material.service.*;
import city.spring.modules.material.vo.MaterialdeliveryMaterialVO;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.swing.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Controller：物资出库与物资关联表
 *
 * @author 谢金婷
 * @date 2020-07-02 13:42:10
 */
@RestController
@RequestMapping("/materialdelivery/{materialdeliveryId}/material")
public class MaterialdeliveryMaterialExtController extends ApiController {
    private final MaterialdeliveryMaterialExtService materialdeliveryMaterialExtService;
    private final MaterialdeliveryMaterialExtRepository deliveryMaterialExtRepository;
    private final MaterialQuantityService materialQuantityService;
    private final MaterialwarehousingMaterialExtService materialwarehousingMaterialExtService;
    private final MaterialreceiptMaterialExtRepository materialreceiptMaterialExtRepository;
    private final MaterialdeliveryService materialdeliveryService;
    private final MaterialreceiptService materialreceiptService;
    private final MaterialwarehousingService materialwarehousingService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<MaterialdeliveryMaterialExtEntity, ?>> entityOrderFields;

    public MaterialdeliveryMaterialExtController(MaterialdeliveryMaterialExtService materialdeliveryMaterialExtService, MaterialdeliveryMaterialExtRepository deliveryMaterialExtRepository, MaterialQuantityService materialQuantityService, MaterialwarehousingMaterialExtService materialwarehousingMaterialExtService, MaterialreceiptMaterialExtRepository materialreceiptMaterialExtRepository, MaterialdeliveryService materialdeliveryService, MaterialreceiptService materialreceiptService, MaterialwarehousingService materialwarehousingService) {
        this.materialdeliveryMaterialExtService = materialdeliveryMaterialExtService;
        this.deliveryMaterialExtRepository = deliveryMaterialExtRepository;
        this.materialQuantityService = materialQuantityService;
        this.materialwarehousingMaterialExtService = materialwarehousingMaterialExtService;
        this.materialreceiptMaterialExtRepository = materialreceiptMaterialExtRepository;
        this.materialdeliveryService = materialdeliveryService;
        this.materialreceiptService = materialreceiptService;
        this.materialwarehousingService = materialwarehousingService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(MaterialdeliveryMaterialExtEntity::getId);
        entityOrderFields.add(MaterialdeliveryMaterialExtEntity::getMaterialdeliveryId);
        entityOrderFields.add(MaterialdeliveryMaterialExtEntity::getMaterialId);
        entityOrderFields.add(MaterialdeliveryMaterialExtEntity::getDeliveryquantity);
        entityOrderFields.add(MaterialdeliveryMaterialExtEntity::getTotal);
    }

    @ModelAttribute
    public void getDeliveryId(@PathVariable String materialdeliveryId) {
        if (materialdeliveryId == null) {
            throw new RuntimeException("出库单ID必须不为空");
        }
        System.out.println("materialdeliveryId" + materialdeliveryId);
    }

    /**
     * 获取全部的 <strong>物资出库与物资关联表</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault Pageable pageable, MaterialdeliveryMaterialExtEntity entity) {
        LambdaQueryChainWrapper<MaterialdeliveryMaterialExtEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

//    /**
//     * 分页获取 <strong>物资出库与物资关联表</strong> 列表
//     *
//     * @param pageable 分页参数信息
//     */
//    @GetMapping
//    public Object list(@PageableDefault Pageable pageable, MaterialdeliveryMaterialExtEntity entity) {
//        LambdaQueryChainWrapper<MaterialdeliveryMaterialExtEntity> lambdaQuery = buildLambdaQuery(entity);
//        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
//        Page<MaterialdeliveryMaterialExtEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
//        return success(page);
//    }

    /**
     * 获取物资出库所有物资列表
     *
     * @param materialdeliveryId 出库单id
     */
    @GetMapping
    public Object list(@PathVariable String materialdeliveryId) {
        return success(deliveryMaterialExtRepository.getDeliveryMaterials(materialdeliveryId));
    }

    /**
     * 获取一个 <strong>物资出库与物资关联表</strong>
     *
     * @param extId 主键ID
     */
//    @GetMapping("{id}")
//    public Object info(@PathVariable String id) {
//        return success(materialdeliveryMaterialExtService.getById(id));
//    }
    @GetMapping("{extId}")
    public Object getInfo(@PathVariable String materialdeliveryId, @PathVariable String extId) {
        return success(deliveryMaterialExtRepository.getDeliveryMaterial(materialdeliveryId, extId));
    }

    /**
     * 添加一个 <strong>物资出库与物资关联表</strong>
     *
     * @param entity 修改后的信息
     */
//    @PostMapping
//    public Object add(@RequestBody MaterialdeliveryMaterialExtEntity entity) {
//        materialdeliveryMaterialExtService.saveMaterialdeliveryMaterialExt(entity);
//
//        HttpHeaders headers = new HttpHeaders();
//        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
//        return new ResponseEntity<>(headers, HttpStatus.CREATED);
//    }

    /**
     * 给出库单添加多个物资信息
     *
     * @param materialdeliveryId 出库单ID
     * @param materials          所添加的物资信息列表
     * @return
     */
    @PostMapping
    public Object addAll(@PathVariable String materialdeliveryId, @RequestBody List<MaterialdeliveryMaterialExtEntity> materials) {
        // 查出已有的数据
        List<MaterialdeliveryMaterialVO> dbMaterials = deliveryMaterialExtRepository.getDeliveryMaterials(materialdeliveryId);
        // 出库单
        MaterialdeliveryEntity materialdeliveryEntity = materialdeliveryService.getById(materialdeliveryId);
        MaterialreceiptEntity materialreceiptEntity = materialreceiptService.getById(materialdeliveryService.getById(materialdeliveryId).getMaterialreceiptId());

        // 数据库已经存在的物资列表
        Set<String> dbMaterialIdsSet = dbMaterials.stream()
                .map(MaterialdeliveryMaterialExtEntity::getMaterialwarehousingMaterialId)
                .collect(Collectors.toSet());
        // 过滤掉已经存在数据库的数据
        List<MaterialdeliveryMaterialExtEntity> needSavematerials = materials.stream()
                .filter(item -> {
                    item.setMaterialdeliveryId(materialdeliveryId);
                    // 总价=数量*单价
                    item.setTotal(item.getDeliveryquantity().multiply(item.getUnitprice()));
                    String warehousingMaterialId = item.getMaterialwarehousingMaterialId();
                    // 过滤出不存在数据库中的数据
                    return warehousingMaterialId != null && !dbMaterialIdsSet.contains(warehousingMaterialId);
                }).collect(Collectors.toList());

        System.out.println("needSavematerials"+needSavematerials);
//        if (!needSavematerials.isEmpty()) {
//            materialdeliveryMaterialExtService.saveBatch(needSavematerials);
//        }


        // 出库数量与剩余数量判断
        // 出库数量和与领用数量盘点
        List<MaterialreceiptMaterialExtEntity> receiptMaterials = materialreceiptMaterialExtRepository.getReceiptMaterials(materialdeliveryEntity.getMaterialreceiptId());
        int mm = 0;
        for (MaterialreceiptMaterialExtEntity receiptMaterial : receiptMaterials) {
            BigDecimal totalquantity = new BigDecimal(0);
            for (MaterialdeliveryMaterialExtEntity material : needSavematerials) {
                if (receiptMaterial.getMaterialId().equals(material.getMaterialId())) {
                    totalquantity = totalquantity.add(material.getDeliveryquantity());
                }
            }
            if (receiptMaterial.getReceiptquantity().compareTo(totalquantity) == 0) {
                mm = mm + 1;
            }
        }
        if (receiptMaterials.size() == mm) {
//            System.out.println("所有的领用数量等于出库数量");
            if (!needSavematerials.isEmpty()) {
                materialdeliveryMaterialExtService.saveBatch(needSavematerials);
            }
            for (MaterialdeliveryMaterialExtEntity material : needSavematerials) {
                // 1.更新库存表库存信息
                MaterialQuantityEntity materialQuantityEntity = materialQuantityService.getByMaterialIdAndStorehouseId(material.getMaterialId(), material.getStorehouseId());
                // 更新出库数量 = 原来的出库数量 + 现在的出库数量
                BigDecimal mdeliveryquantity = materialQuantityEntity.getDeliveryquantity() == null ? BigDecimal.ZERO : materialQuantityEntity.getDeliveryquantity();
                materialQuantityEntity.setDeliveryquantity(mdeliveryquantity.add(material.getDeliveryquantity()));
                // 更新库存=原来的库存-现在的出库数量
                BigDecimal mquantity = materialQuantityEntity.getQuantity() == null ? BigDecimal.ZERO : materialQuantityEntity.getQuantity();
                materialQuantityEntity.setQuantity(mquantity.subtract(material.getDeliveryquantity()));
                materialQuantityEntity.setTotal(materialQuantityEntity.getUnitprice().multiply(materialQuantityEntity.getQuantity()));
                // 平均价格
                if (materialQuantityEntity.getTotal().compareTo(BigDecimal.ZERO) == 0 || materialQuantityEntity.getQuantity().compareTo(BigDecimal.ZERO) == 0) {
                    materialQuantityEntity.setUnitprice(BigDecimal.ZERO);
                } else {
                    materialQuantityEntity.setUnitprice(materialQuantityEntity.getTotal().divide(materialQuantityEntity.getQuantity(), 2));
                }
                materialQuantityService.lambdaUpdate()
                        .set(MaterialQuantityEntity::getDeliveryquantity, materialQuantityEntity.getDeliveryquantity())
                        .set(MaterialQuantityEntity::getQuantity, materialQuantityEntity.getQuantity())
                        .set(MaterialQuantityEntity::getTotal, materialQuantityEntity.getTotal())
                        .set(MaterialQuantityEntity::getUnitprice, materialQuantityEntity.getUnitprice())
                        .eq(MaterialQuantityEntity::getId, materialQuantityEntity.getId())
                        .update();

                // 2.更新入库物资表剩余数量
                MaterialwarehousingMaterialExtEntity materialwarehousingMaterialExtEntity = materialwarehousingMaterialExtService.getById(material.getMaterialwarehousingMaterialId());
                BigDecimal remainingQuantity = materialwarehousingMaterialExtEntity.getRemainingQuantity() == null ? BigDecimal.ZERO : materialwarehousingMaterialExtEntity.getRemainingQuantity();
                materialwarehousingMaterialExtEntity.setRemainingQuantity(remainingQuantity.subtract(material.getDeliveryquantity()));
                materialwarehousingMaterialExtService.lambdaUpdate()
                        .set(MaterialwarehousingMaterialExtEntity::getRemainingQuantity, materialwarehousingMaterialExtEntity.getRemainingQuantity())
                        .eq(MaterialwarehousingMaterialExtEntity::getId, materialwarehousingMaterialExtEntity.getId())
                        .update();

                // 3.物资出库后修改该物资入库单为 不可以作废 状态
                MaterialwarehousingEntity materialwarehousingEntity = materialwarehousingService.getById(materialwarehousingMaterialExtEntity.getMaterialwarehousingId());
                materialwarehousingEntity.setIsCan("不可以");
                materialwarehousingService.lambdaUpdate()
                        .set(MaterialwarehousingEntity::getIsCan, materialwarehousingEntity.getIsCan())
                        .eq(MaterialwarehousingEntity::getId, materialwarehousingEntity.getId())
                        .update();
            }
        } else {
            // 出库数量不等于领用申请数量 不能生成出库单
            // 修改出库状态为未出库
            materialreceiptEntity.setDeliveryStatus("未出库");
            materialreceiptService.lambdaUpdate()
                    .set(MaterialreceiptEntity::getDeliveryStatus, materialreceiptEntity.getDeliveryStatus())
                    .eq(MaterialreceiptEntity::getId, materialreceiptEntity.getId())
                    .update();
            // 删除生成的出库单
            materialdeliveryService.deleteMaterialdelivery(String.valueOf(materialdeliveryService.getById(materialdeliveryId).getId()));
            // 窗口提示
//            JOptionPane.showMessageDialog(null, "出库数量不等于领用申请数量", "错误", JOptionPane.INFORMATION_MESSAGE);
            throw new RuntimeException("出库数量不等于领用申请数量");
        }
        return success(null);
    }

    /**
     * 修改一个 <strong>物资出库与物资关联表</strong>
     *
     * @param materialdeliveryId 出库单ID
     * @param extId              关联ID
     * @param extEntity          接收的数据
     */
//    @PutMapping("{id}")
//    public Object update(@PathVariable String id, @RequestBody MaterialdeliveryMaterialExtEntity entity) {
//        entity.setId(id);
//        materialdeliveryMaterialExtService.updateMaterialdeliveryMaterialExt(entity);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    @PutMapping("{extId}")
    public Object update(@PathVariable String materialdeliveryId, @PathVariable String extId, @RequestBody MaterialdeliveryMaterialExtEntity extEntity) {
        extEntity.setId(extId);
        extEntity.setMaterialdeliveryId(materialdeliveryId);
        materialdeliveryMaterialExtService.updateMaterialdeliveryMaterialExt(extEntity);
        return success(null);
    }

    /**
     * 删除一个 <strong>物资出库与物资关联表</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        materialdeliveryMaterialExtService.deleteMaterialdeliveryMaterialExt(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong>物资出库与物资关联表</strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        materialdeliveryMaterialExtService.deleteMaterialdeliveryMaterialExt(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<MaterialdeliveryMaterialExtEntity> buildLambdaQuery(MaterialdeliveryMaterialExtEntity entity) {
        LambdaQueryChainWrapper<MaterialdeliveryMaterialExtEntity> lambdaQuery = materialdeliveryMaterialExtService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), MaterialdeliveryMaterialExtEntity::getId, entity.getId());
        lambdaQuery.eq(entity.getMaterialdeliveryId() != null, MaterialdeliveryMaterialExtEntity::getMaterialdeliveryId, entity.getMaterialdeliveryId());
        lambdaQuery.eq(entity.getMaterialId() != null, MaterialdeliveryMaterialExtEntity::getMaterialId, entity.getMaterialId());
        lambdaQuery.eq(entity.getDeliveryquantity() != null, MaterialdeliveryMaterialExtEntity::getDeliveryquantity, entity.getDeliveryquantity());
        lambdaQuery.eq(entity.getTotal() != null, MaterialdeliveryMaterialExtEntity::getTotal, entity.getTotal());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private QueryWrapper<MaterialdeliveryMaterialExtEntity> buildQuery(MaterialdeliveryMaterialExtEntity entity) {
        QueryWrapper<MaterialdeliveryMaterialExtEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "id", entity.getId());
        wrapper.eq(entity.getMaterialdeliveryId() != null, "materialdelivery_id", entity.getMaterialdeliveryId());
        wrapper.eq(entity.getMaterialId() != null, "material_id", entity.getMaterialId());
        wrapper.eq(entity.getDeliveryquantity() != null, "quality", entity.getDeliveryquantity());
        wrapper.eq(entity.getTotal() != null, "total", entity.getTotal());
        return wrapper;
    }

}
